/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.controller.func;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.je.common.base.DynaBean;
import com.je.common.base.mvc.AbstractPlatformController;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.result.BaseRespResult;
import com.je.common.base.util.ArrayUtils;
import com.je.common.base.util.MessageUtils;
import com.je.common.base.util.SecurityUserHolder;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.cache.func.FuncConfigCache;
import com.je.meta.cache.func.FuncInfoCache;
import com.je.meta.cache.func.FuncStaticizeCache;
import com.je.meta.cache.funcperm.FuncPermCache;
import com.je.meta.service.MetaStaticizeService;
import com.je.meta.service.func.FuncPermService;
import com.je.meta.service.func.MetaFuncInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/je/meta/staticize")
public class StaticizeController extends AbstractPlatformController {

    @Autowired
    protected MetaFuncInfoService funcInfoService;
    @Autowired
    private MetaStaticizeService metaStaticizeService;
    @Autowired
    private FuncStaticizeCache funcStaticizeCache;
    @Autowired
    private FuncInfoCache funcInfoCache;
    @Autowired
    private FuncConfigCache funcConfigCache;
    @Autowired
    private FuncPermCache funcPermCache;
    @Autowired
    private FuncPermService funcPermService;

    /**
     * 静态化功能
     */
    @RequestMapping(value = "/doFuncInfo", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult doFuncInfo(BaseMethodArgument param, HttpServletRequest request) {
        String strDataEn = getStringParameter(request, "strData_en");
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        String strData = param.getStrData();
        metaStaticizeService.doFuncInfo(dynaBean.getStr("FUNCINFO_FUNCCODE"), strData, strDataEn);
        return BaseRespResult.successResult(null, "静态化成功");
    }

    /**
     * 静态化功能
     */
    @RequestMapping(value = "/doFuncInfo4Zh", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult doFuncInfo4Zh(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        String strData = param.getStrData();
        funcStaticizeCache.putCache(dynaBean.getStr("FUNCINFO_FUNCCODE"), strData);
        return BaseRespResult.successResult(null, "静态化成功");
    }

    /**
     * 通过功能编码得到一条配置信息
     */
    @RequestMapping(value = "/getStaticFuncByCode", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public Map<String, Object> getStaticFuncByCode(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        //是否刷新
        Boolean refresh = Boolean.parseBoolean(getStringParameter(request, "refresh"));
        //租户ID获取
        String currentAccountTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        Map<String, Object> resultConfig;

        if (!refresh) {
            if (Strings.isNullOrEmpty(currentAccountTenantId)) {
                resultConfig = funcConfigCache.getCacheValue(dynaBean.getStr("FUNCINFO_FUNCCODE"));
            } else {
                resultConfig = funcConfigCache.getCacheValue(currentAccountTenantId, dynaBean.getStr("FUNCINFO_FUNCCODE"));
            }
            if (resultConfig != null) {
                return resultConfig;
            }
        }

        if (Strings.isNullOrEmpty(currentAccountTenantId)) {
            funcInfoCache.removeCache(dynaBean.getStr("FUNCINFO_FUNCCODE"));
            funcConfigCache.removeCache(dynaBean.getStr("FUNCINFO_FUNCCODE"));
        } else {
            funcInfoCache.removeCache(currentAccountTenantId, dynaBean.getStr("FUNCINFO_FUNCCODE"));
            funcConfigCache.removeCache(currentAccountTenantId, dynaBean.getStr("FUNCINFO_FUNCCODE"));
        }

        DynaBean funcInfo = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", dynaBean.getStr("FUNCINFO_FUNCCODE")));
        resultConfig = funcInfoService.getFuncConfigInfo(funcInfo);
        if (Lists.newArrayList("FUNC", "TREE", "VIEW").contains(funcInfo.getStr("FUNCINFO_FUNCTYPE"))) {
            metaService.clearMyBatisFuncCache(dynaBean.getStr("FUNCINFO_FUNCCODE"));
        }
        //清理Mybatis功能缓存
        metaService.clearMyBatisFuncCache(dynaBean.getStr("FUNCINFO_FUNCCODE"));

        return resultConfig;
    }

    /**
     * 通过功能编码得到一条配置信息
     */
    @RequestMapping(value = "/getStaticFuncPermByCode", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public Map<String, Object> getStaticFuncPermByCode(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        //是否刷新
        Boolean refresh = Boolean.parseBoolean(getStringParameter(request, "refresh"));
        //租户ID获取
        String currentAccountTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        String funcCode = dynaBean.getStr("FUNCINFO_FUNCCODE");
        Map<String, Object> resultConfig;

        if (!refresh) {
            if (Strings.isNullOrEmpty(currentAccountTenantId)) {
                resultConfig = funcPermCache.getCacheValue(funcCode);
            } else {
                resultConfig = funcPermCache.getCacheValue(currentAccountTenantId, funcCode);
            }

            if (resultConfig != null) {
                return resultConfig;
            }
        }

        if(Strings.isNullOrEmpty(currentAccountTenantId)){
            funcPermCache.removeCache(funcCode);
        }else {
            funcPermCache.removeCache(currentAccountTenantId, funcCode);
        }
        resultConfig = funcPermService.getFuncConfigInfo(funcCode);
        //清理Mybatis功能缓存
        metaService.clearMyBatisFuncCache(funcCode);
        return resultConfig;
    }

    /**
     * 获取所有功能最后静态化时间
     */
    @RequestMapping(value = "/getStaticFuncTime", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public Map<String, Object> getStaticFuncTime(BaseMethodArgument param, HttpServletRequest request) {
        String codes = getStringParameter(request, "codes");
        String userId = getStringParameter(request, "userId");
        if (Strings.isNullOrEmpty(userId)) {
            userId = SecurityUserHolder.getCurrentAccount().getId();
        }
        Map<String, Object> result = Maps.newHashMap();
        List<Map<String, Object>> staticFuncVersions;
        String[] codesArr = null;
        if (Strings.isNullOrEmpty(codes)) {
            staticFuncVersions = metaService.selectSql("SELECT FUNCINFO_FUNCCODE,FUNCINFO_ZHJTSJ FROM JE_CORE_FUNCINFO");
            if (staticFuncVersions != null && staticFuncVersions.size() > 0) {
                codesArr = new String[staticFuncVersions.size()];
                for (int i = 0; i < staticFuncVersions.size(); i++) {
                    codesArr[i] = (String) staticFuncVersions.get(i).get("FUNCINFO_FUNCCODE");
                }
            }
        } else {
            codesArr = codes.split(ArrayUtils.SPLIT);
            staticFuncVersions = metaService.selectSql("SELECT FUNCINFO_FUNCCODE,FUNCINFO_ZHJTSJ FROM JE_CORE_FUNCINFO WHERE FUNCINFO_FUNCCODE IN ({0})", Arrays.asList(codesArr));
        }
        result.put("funcVersions", staticFuncVersions);
        return result;
    }

    /**
     * 清除功能静态化
     *
     * @param param
     */
    @RequestMapping(value = "/clearStaticize", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult clearStaticize(BaseMethodArgument param, HttpServletRequest request) {
        String funcCode = param.getFuncCode();
        String productCode = getStringParameter(request, "productCode");
        if (StringUtil.isNotEmpty(funcCode) && funcCode.contains(",")) {
            String[] funcCodeArr = funcCode.split(",");
            for (int i = 0; i < funcCodeArr.length; i++) {
                if(StringUtil.isNotEmpty(funcCodeArr[i])){
                    metaStaticizeService.removeCache(funcCodeArr[i], productCode);
                }
            }
        } else {
            metaStaticizeService.removeCache(funcCode, productCode);
        }
        return BaseRespResult.successResult(MessageUtils.getMessage("common.operation.success"));
    }
}
